package com.hmall.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmall.clients.AddressClient;
import com.hmall.clients.ItemClient;
import com.hmall.common.BaseContext;
import com.hmall.common.pojo.Address;
import com.hmall.common.pojo.Item;
import com.hmall.order.mapper.OrderMapper;
import com.hmall.order.pojo.Order;
import com.hmall.order.pojo.OrderDetail;
import com.hmall.order.pojo.OrderLogistics;
import com.hmall.order.pojo.RequestParams;
import com.hmall.order.service.IOrderDetailService;
import com.hmall.order.service.IOrderLogisticsService;
import com.hmall.order.service.IOrderService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;

@Service
@Slf4j
public class OrderService extends ServiceImpl<OrderMapper, Order> implements IOrderService {
    @Autowired
    private ItemClient client;

    @Autowired
    private IOrderDetailService orderDetailService;

    @Autowired
    private AddressClient addressClient;

    @Autowired
    private IOrderLogisticsService orderLogisticsService;

    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 创建订单
     * @param dto
     */
    @GlobalTransactional
    @Override
    public Long submitOrder(RequestParams dto) {
        Item item = client.getById(dto.getItemId());
        Long price = item.getPrice();
        Integer num = dto.getNum();
        long totalFee = price * num;
        Order order = new Order();
        order.setTotalFee(Integer.parseInt(String.valueOf(totalFee)));
        order.setPaymentType(dto.getPaymentType());
        order.setUserId(BaseContext.getCurrentId());
        order.setStatus(1);
        save(order);

        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(order.getId());
        orderDetail.setItemId(item.getId());
        orderDetail.setNum(num);
        orderDetail.setTitle(item.getName());
        orderDetail.setPrice(price);
        orderDetail.setSpec(item.getSpec());
        orderDetail.setImage(item.getImage());

        orderDetailService.save(orderDetail);

        Address address = addressClient.findAddressById(Long.valueOf(dto.getAddressId()));

        OrderLogistics orderLogistics = new OrderLogistics();
        orderLogistics.setOrderId(order.getId());
        orderLogistics.setContact(address.getContact());
        orderLogistics.setPhone(address.getMobile());
        orderLogistics.setProvince(address.getProvince());
        orderLogistics.setCity(address.getCity());
        orderLogistics.setTown(address.getTown());
        orderLogistics.setStreet(address.getStreet());
        orderLogisticsService.save(orderLogistics);

        client.updateStock(item.getId(),dto.getNum());

        Message message = MessageBuilder
                .withBody(order.getId().toString().getBytes(StandardCharsets.UTF_8))
                .setExpiration("10000")//延迟时间
                .build();

        //消息id,封装到CorrelationData中
        CorrelationData correlationData = new CorrelationData(order.getId().toString());
        //发送消息
        rabbitTemplate.convertAndSend("order.topic","order",message,correlationData);
        return order.getId();
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "dl.ttl.queue",declare = "true"),
            exchange = @Exchange(name = "dl.ttl.exchange"),
            key = "dl"
    ))
    public void listenDlQueue(String msg){
        log.info("接收到死信交换机的消息,{}",msg);
        Long orderId = Long.valueOf(msg);
        Order order = getById(orderId);
        Integer status = order.getStatus();
        if (status == 1){
            order.setStatus(5);
            updateById(order);
            LambdaQueryWrapper<OrderDetail> lqw = new LambdaQueryWrapper<>();
            lqw.eq(OrderDetail::getOrderId,orderId);
            OrderDetail orderDetail = orderDetailService.getOne(lqw);
            Long itemId = orderDetail.getItemId();
            Item item = client.getById(itemId);
            item.setStock(item.getStock()+orderDetail.getNum());
            client.update(item);
        }
    }
}
